package edu.snake.implement;


import edu.snake.core.model.arena.Arena;
import edu.snake.core.model.character.Character;
import edu.snake.core.model.character.CharacterState;
import edu.snake.core.model.character.CharactersBuilder;
import edu.snake.implement.model.CharacterName;
import edu.snake.implement.model.arena.ArenaImpl;
import edu.snake.implement.model.character.CharacterImpl;
import edu.snake.implement.model.character.movement.CourseImplSnake;
import edu.snake.implement.model.character.movement.RandomMoveSimple;
import edu.snake.implement.model.character.movement.SnakeMove02;

import static edu.snake.implement.ConfigConstant.getInstanceGameEngine;
import static edu.snake.implement.ConfigConstant.getInstanceLiveOrDieService;

public class CharactersFactory implements CharactersBuilder<CharacterName> {
    private final Character characterBorder = new CharacterImpl(CharacterName.BORDER);

    @Override
    public Character createNewCharacter(CharacterName characterName) {
        Character character;
        switch (characterName) {
            case SNAKE_HEAD:
                int snakeSize = ConfigConstant.snakeSize;
                character = new CharacterImpl(CharacterName.SNAKE_HEAD, new CourseImplSnake());
                character.setState(CharacterState.WITH_ELEMENT);
                character.setAlive(true);
                character.setMovement(new SnakeMove02(character, getInstanceGameEngine().getArena(), getInstanceLiveOrDieService()));
                character.setCourse(new CourseImplSnake());
                for (int i = 1; i < snakeSize; i++) {
                    if (i == snakeSize - 1) {
                        character.add(new CharacterImpl(CharacterName.SNAKE_TAIL));
                    } else {
                        character.add(new CharacterImpl(CharacterName.SNAKE));
                    }
                }
                return character;

            case FROG:
                character = new CharacterImpl(CharacterName.FROG);
                character.setMovement(new RandomMoveSimple(character, getInstanceGameEngine().getArena(), getInstanceLiveOrDieService()));
                character.setAlive(true);
                return character;
            case SNAKE_TAIL:
                return new CharacterImpl(CharacterName.SNAKE_TAIL);
            case SNAKE:
                return new CharacterImpl(CharacterName.SNAKE);
            case BORDER:
                return characterBorder;
        }
        throw new IllegalArgumentException("Characters not builds, Arguments characterName not recognized.");
    }

    @Override
    public Arena createNewArena() {
        return new ArenaImpl(ConfigConstant.cellWidth, ConfigConstant.cellHeight);
    }
}
